// import { JUMP, LADDER, LEFT, NONE, RIGHT, ROPE, STABO1, STABO2, STAND1, SWINGO1, UP, WALK1, DOWN } from "../net/code.js";
// import playerMove from "../net/eventPacket.js";
import { Container } from 'pixi.js'
import { Physics, PhysicsObject } from "@tsdy/maplestory-physics";
import sceneContainer from "../scene/container.js";
import { offAllClock, upAllClock } from "./player/clock.js";
import { eventMixin } from "./player/eventMixin.js";
import { init } from "./player/init.js";
import { addNum, descreaseBlood, hurt, inscreaseBlood, numUpdate, recover } from "./player/number.js";
import { update } from "./player/update.js";

export function Player(resource, stage, keyboard) {
  this.phobj = new PhysicsObject();
  this.physics = null
  // 是否开启物理引擎
  this.isPhysics = true

  this.state = "stand1";
  this.stage = stage;
  // 正在传送
  this.isTransfering = false;
  // 可以阻止update函数
  this.isStop = false;
  this.container = new Container();
  this.container.sortableChildren = true;
  this.Info = null;

  this.clockMap = {
    4000: null
  };

  this.ability = {
    recoverRate: 10,
    bodyAttack: 4,
  };

  // IO
  this.keyboard = keyboard;

  this.resource = resource;

  this.attackLock = false; // 攻击时不能移动，跳跃，再次攻击
  this.ladderRopeLock = false;
  this.jumpLock = false;

  this.leftJump = false;
  this.rightJump = false;

  this.holding = true;
  this.foodHold = null;

  this.ladderRope = null;

  this.ladders = [];
  this.ropes = [];

  this.performance = {
    alert: null,
    stand1: null,
    jump: null,
    walk1: null,
    swingO1: null,
    stabO1: null,
    stabO2: null,
    ladder: null,
    rope: null,
  };
  this.direction = {
    up() {
      this.upChange = true;
      this.isUp = true;
    },
    bottom() {
      this.isBottom = true;
    },
    stand() {
      this.isStand = true;
    },
    walk() {
      this.isWalk = true;
    },
    left() {
      this.beforeLeft = this.isLeft;
      this.isLeft = true;
    },
    right() {
      this.beforeRight = this.isRight;
      this.isRight = true;
    },
    jump() {
      this.isJump = true;
    },
    attack() {
      this.isAttack = true;
    },
    ladder() {
      this.isLadder = true;
    },
    stopLadder() {
      this.isLadder = false;
    },
    stopLeft() {
      this.beforeLeft = this.isLeft;
      this.isLeft = false;
    },
    stopRight() {
      this.beforeRight = this.isRight;
      this.isRight = false;
    },
    stopUp() {
      this.upChange = true;
      this.isUp = false;
    },
    stopBottom() {
      this.isBottom = false;
    },
    stopJump() {
      this.isJump = false;
    },
    stopAttack() {
      this.isAttack = false;
    },
    stopLadder() {
      this.isLadder = false;
    },
    getUpChange() {
      if (this.upChange) {
        this.upChange = false;
        return true;
      }
      return false;
    },

    beforeLeft: false,
    beforeRight: false,
    isLeft: false,
    isRight: false,
    isUp: false,
    upChange: false,
    isBottom: false,
    isJump: false,
    isAttack: false,
    isWalk: false,
    isStand: false,
    isLadder: false,
  };

  this.animationSprite = null;

  let _position = {
    x: 917,
    y: 526,
  };
  this.phobj.set_x(917)
  this.phobj.set_y(526)

  // 尽量不要在其他地方操作phobj的属性
  this.position = new Proxy(_position, {
    set: (target, key, value) => {
      if (key === "x") {
        this.container[key] = Number(value);
        this.phobj.set_x(Number(value))
      }
      if (key === "y") {
        this.container[key] = Number(value);
        this.phobj.set_y(Number(value))
      }
      return Reflect.set(target, key, value);
    },
    get: (target, key) => {
      if (key === 'x') {
        return this.phobj.crnt_x()
      } else if (key === 'y') {
        return this.phobj.crnt_y()
      }
    }
  });
  this.xSpeed = 1;
  this.ySpeed = 6.2;
  this.baseYspeed = 2;
  this.gravity = 0.5;
  this.layer = 0;
  this.fhId = 0;
  this.numberArray = [];
  this.numSpeed = 0.5;
  this.numHeight = 40;

  // 为真时，才能被攻击
  this.allowAttacked = true;
  // 被攻击后为真，用来停止攻击效果和攻击特效
  this.isAttacked = false;

  // 被攻击后的无敌时间
  this.attackedInterval = 2500;
  // 攻击范围
  this.attackRange = 100;

  this.attackedDrop = -1;

  // 移除攻击效果
  this.afterImageLock = false;
}

Player.prototype.switchPhysics = function(footholds) {
  this.physics = new Physics(footholds)
}

Player.prototype.upAllClock = upAllClock;
Player.prototype.offAllClock = offAllClock;

Player.prototype.load = async function () {
    const resource = this.resource;
    const {bodyId, headId, faceId, weaponId, hairId, coatId, pantsId} = this.Info;
    await resource.loadPlayer(this.Info)
};

Player.prototype.numUpdate = numUpdate;
Player.prototype.addNum = addNum;
Player.prototype.increaseBlood = inscreaseBlood;
Player.prototype.descreaseBlood = descreaseBlood;
Player.prototype.recover = recover
Player.prototype.hurt = hurt;

Player.prototype.init = init;

Player.prototype.changePerformance = function () {
  if (this.attackLock) {
    return;
  }
  const {
    isAttack,
    isJump,
    isLeft,
    isRight,
    isStand,
    isWalk,
    isBottom,
    isUp,
    isLadder,
  } = this.direction;
  if (isLadder) {
    if (this.ladderRope.isLadder()) {
      this.ladder();
    } else {
      this.rope();
    }
    // if (isJump && isLadder && (isLeft || isRight)) {
    //   this.jumpLock = true;
    //   this.ySpeed = -8;
    //   this.jump();
    //   this.leftJump = this.rightJump = false;
    //   if (isLeft) {
    //     this.leftJump = true;
    //     this.direction.stopLadder();
    //   } else if (isRight) {
    //     this.rightJump = true;
    //     this.direction.stopLadder();
    //   }
    //   return;
    // }
    return;
  }
  if (isAttack && !this.attackLock) {
    this.attackLock = true;
    let type = Math.random();
    if (type <= 0.3) {
      this.stabO1();
    } else if (type > 0.3 && type <= 0.6) {
      this.swingO1();
    } else {
      this.stabO2();
    }
    return;
  }
  if (!this.holding) {
    this.jump();
  }
  // if ((isJump && this.holding) || (isJump && isLadder)) {
  //   this.jumpLock = true;
  //   this.ySpeed = -8;
  //   this.jump();
  //   this.leftJump = this.rightJump = false;
  //   if (isLeft) {
  //     this.leftJump = true;
  //   } else if (isRight) {
  //     this.rightJump = true;
  //   }
  //   return;
  // }
  if (isLeft || isRight) {
    if (isLeft) {
      this.turnToLeft();
    } else if (isRight) {
      this.turnToRight();
    }
    if (this.holding) {
      this.walk1();
    }
    return;
  }

  if (this.holding) {
    this.stand1();
  }
};

Player.prototype.update = update;

Player.prototype.isLeft = function () {
  return this.container.scale.x === 1;
};

Player.prototype.isRight = function () {
  return this.container.scale.x === -1;
};

/**
 *
 * @param { string } goalAniName
 */
Player.prototype.transform = function (goalAniName) {
  if (this.state === goalAniName) {
    return;
  }
  this.state = goalAniName;
  let nextAni = this.performance[goalAniName];
  let nowAni = this.animationSprite;
  // nowAni.gotoAndStop(0);
  // nextAni.scale.x = nowAni.scale.x;
  this.container.removeChild(nowAni);
  this.animationSprite = nextAni;
  this.animationSprite.gotoAndPlay(0);
  this.container.addChild(this.animationSprite);
};

Player.prototype.setLayer = function (layer, stage) {
  if (this.layer === layer) {
    return;
  }

  this.layer = layer;
  this.container.zIndex = layer;
  stage.removeChild(this.container);
  stage.addChild(this.container);
};

Player.prototype.stand1 = function () {
  this.transform("stand1");
};

Player.prototype.jump = function () {
  this.transform("jump");
};

Player.prototype.alert = function () {
  this.transform("alert");
};

Player.prototype.walk1 = function () {
  this.transform("walk1");
};

Player.prototype.swingO1 = function () {
  this.transform("swingO1");
};

Player.prototype.stabO2 = function () {
  this.transform("stabO2");
};

Player.prototype.stabO1 = function () {
  this.transform("stabO1");
};

Player.prototype.ladder = function () {
  this.transform("ladder");
};

Player.prototype.rope = function () {
  this.transform("rope");
};

Player.prototype.turnToRight = function () {
  if (this.animationSprite.scale.x === 1) {
    // this.animationSprite.x -= (this.animationSprite.width)
  }
  this.container.scale.x = -1;
};

Player.prototype.turnToLeft = function () {
  if (this.animationSprite.scale.x === -1) {
    // this.animationSprite.x += (this.animationSprite.width)
  }
  this.container.scale.x = 1;
};

Player.prototype.stopDrop = function () {
  this.ySpeed = this.baseYspeed;
  this.leftJump = this.rightJump = false;
};

Player.prototype.getWidth = function () {
  return Math.abs(this.container.width);
};

Player.prototype.getHeight = function () {
  return this.container.height;
};

Player.prototype.startAni = function () {
  this.animationSprite.play();
};

Player.prototype.stopAni = function () {
  this.animationSprite.stop();
};

/**
 *
 * @param {number} number 攻击伤害值
 * @param {number} attackSit 0 从左边， 1 从右边
 */
Player.prototype.attacked = function (number, attackSit) {
  this.descreaseBlood(number);
  // 如果收到的伤害为0，就不会收到影响
  if (number === 0) {
    return;
  }
  this.isAttacked = true;
  this.breakAttack();
  this.direction.stopLadder();
  this.transform("jump");
  this.ySpeed = -4;
  if (attackSit === 0) {
    this.attackedDrop = 0;
  } else if (attackSit === 1) {
    this.attackedDrop = 1;
  }
  this.allowAttacked = false;
  setTimeout(() => {
    this.allowAttacked = true;
  }, this.attackedInterval);
};

Player.prototype.attack = function () {
  sceneContainer.mobs.forEach((mob) => {
    if (this.isLeft()) {
      if (
        mob.position.x <= this.position.x &&
        mob.position.x >= this.position.x - this.attackRange
      ) {
        if (
          mob.position.y >= this.position.y - this.getHeight() / 2 &&
          mob.position.y <= this.position.y
        ) {
          mob.attacked(this.ability.bodyAttack);
        }
      }
    } else if (this.isRight()) {
      if (
        mob.position.x >= this.position.x &&
        mob.position.x <= this.position.x + this.attackRange
      ) {
        if (
          mob.position.y >= this.position.y - this.getHeight() / 2 &&
          mob.position.y <= this.position.y
        ) {
          mob.attacked(this.ability.bodyAttack);
        }
      }
    }
  });
};

Player.prototype.transfer = async function() {
  if (this.isTransfering) {
    return ;
  }
  this.isTransfering = true;
  let result = await this.onTransfer();
  this.isTransfering = false;
}

// 中断攻击，例如被怪物攻击后调用
Player.prototype.breakAttack = function () {
  // 处于攻击状态
  if (this.afterImageAni[this.state]) {
    this.container.removeChild(this.afterImageAni[this.state].ani);
    this.performance[this.state].stop();
    this.attackLock = false;
  }
};

Player.prototype.stop = function () {
  this.stage.removeChild(this.container);
  this.isStop = true;

}

Player.prototype.play = function() {
  this.stage.addChild(this.container);
  this.isStop = false;
}

Player.prototype.destroy = function() {
  this.stage.removeChild(this.container);
  Object.values(this.performance).forEach(item => {
    if (item) {
      item.destroy();
    }
  })
  this.performance = {
    alert: null,
    stand1: null,
    jump: null,
    walk1: null,
    swingO1: null,
    stabO1: null,
    stabO2: null,
    ladder: null,
    rope: null,
  };
  this.numberArray.forEach(num => {
    this.stage.removeChild(num);
  })
  this.numberArray = [];
}

eventMixin(Player);